#ifndef CLIENTCLIENTTASK_H
#define CLIENTCLIENTTASK_H

#include <string>
#include <ostream>
#include <doors/ptb.h>
#include <doors/udp.h>
#include <doors/ptask.h>
#include <doors/inetaddr.h>
#include <doors/timer.h>
#include "coapclientsap.h"
#include "coapclientsm.h"
#include "coappdu.h"
#include "options.h"

class CoapClientTaskSM;

class CoapClientTask : public PTask {

  public:
   CoapClientTask(std::string name, Scheduler* s, 
		  CoapClientTaskSM* sm, InetAddr serveraddr);
   virtual ~CoapClientTask();

   // Idle state
   bool idle_Default(Message* msg) { delete msg; return false; }
   bool idle_Cgetreq(Message* msg);
   bool idle_Cpostreq(Message* msg);
   bool idle_Cputreq(Message* msg);
   bool idle_Cdeletereq(Message* msg);
   
   // Wait state
   bool wait_Default(Message* msg) { delete msg; return false; }
   bool wait_ACK(Message* msg);
   bool wait_RST(Message* msg);
   bool wait_Timeout(Message* msg);

   UdpSAP::User down;      
   CoapClientSAP::Provider up;
   CoapPeer peer;        

   
   // Helper functions
  private:
   template <typename T>
      void sendMsg(const T& pdu);
   template <typename T>
      void recvMSg(const T& pdu);
   Uint8 getToken(void);
   void setMsgID(void);
   Uint16 getMsgID(void) const;
   Options& getOptions(void); 
  
  // Class variables
   Uint32 retries_;
   Uint8 token_;
   Uint16 msgID_;
   Frame options_;
   Frame payload_;
   InetAddr serveraddr_;
   Timer timer_;
   CoapPeer::CON* pdu_;
   Options opt;
};

///////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////

template <typename T>
void CoapClientTask::sendMsg(const T& pdu)
{
   // Destination address
   pdu->addr = serveraddr_;

   // Reset timer
   timer_.start();

   // Send data to the peer
   peer.putMessage(pdu);
   std::cout << "***************SENDING CON***********************" << std::endl; 
}

template <typename T>
void CoapClientTask::recvMSg(const T& pdu)
{

}

#endif // CLIENTCLIENTTASK_H
